#include "nb_msg.h"

NB_Msg::NB_Msg()
{
	Reset();
}

void NB_Msg::Reset()
{
	ZeroMemory(&overlapped, sizeof(WSAOVERLAPPED));
	wsabuf.buf = buffer;
	wsabuf.len = BUFFER_SIZE - 1;
	ZeroMemory(buffer, BUFFER_SIZE);
	dwFlags = 0;
}


NB_MsgManager::NB_MsgManager(int nMaxSize)
{
	m_nMaxSize = nMaxSize > 0 ? nMaxSize : 100;

	m_pMsgArray = new NB_Msg[m_nMaxSize];
	for(int i = 0; i < m_nMaxSize; i++)
		m_FreeList.push_back(&m_pMsgArray[i]);

	m_pCsLock = new CsLock();
}

NB_MsgManager::~NB_MsgManager()
{
	m_FreeList.clear();
	m_UsedList.clear();
	if(m_pMsgArray) delete[] m_pMsgArray;
	m_pMsgArray = NULL;

	if(m_pCsLock) delete m_pCsLock;
	m_pCsLock = NULL;
}

NB_Msg * NB_MsgManager::Create()
{
	NB_Msg * lpMsg = NULL;

	m_pCsLock->Lock();

	if(m_FreeList.size() == 0)
	{
		m_pCsLock->Unlock();
		return lpMsg;
	}

	lpMsg = m_FreeList.back();
	lpMsg->pos = (DWORD)m_UsedList.size();
	m_UsedList.push_back(lpMsg);
	m_FreeList.pop_back();

	m_pCsLock->Unlock();

	return lpMsg;
}

void NB_MsgManager::Free(NB_Msg * lpMsg)
{
	if(lpMsg != NULL)
	{
		m_pCsLock->Lock();

		m_UsedList.back()->pos = lpMsg->pos;
		swap(m_UsedList[lpMsg->pos], m_UsedList.back());
		m_FreeList.push_back(lpMsg);
		m_UsedList.pop_back();
		closesocket(lpMsg->socket);

		m_pCsLock->Unlock();
	}
}